package com.qfjy.controller;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.qfjy.client.VideoInfoControllerFeignClient;
import com.qfjy.entity.po.MeetingPub;
import com.qfjy.service.MeetingPubService;
import com.qfjy.util.result.ResultCode;
import com.qfjy.util.result.ResultJson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

/**
 * @ClassName MeetingPubController
 * @Description TODO
 * @Author guoweixin
 * @Date 2021/8/18
 * @Version 1.0
 */
@Controller
@RequestMapping("meetingPub")
@Slf4j
@DefaultProperties(defaultFallback = "defaultFallback")
public class MeetingPubController {

    @Autowired
    private MeetingPubService meetingPubService;


    @Autowired
    private VideoInfoControllerFeignClient videoInfoControllerFeignClient;

    /**
     * 根据会议编号查询会议详细信息
     */
    @GetMapping("{pcode}")   // meetingPub/pcode
    @ResponseBody
    public Object selectById(@PathVariable("pcode")  String pcode){
         MeetingPub meetingPub= meetingPubService.selectMeetingPubByPcode(pcode);

         if(meetingPub==null){
             return  new ResultJson<>(null, ResultCode.NOT_DATA);
         }

         log.info("会议微服务---》根据会议编号查询会议信息-->"+meetingPub);

        /**
         * 查询视频微服务相关信息
         */
         String result= videoInfoControllerFeignClient.selectVideoInfoByPcode(meetingPub.getPcode());

        meetingPub.setRemark(result);

        return new ResultJson<>(meetingPub,ResultCode.SUCCESS);
    }

    @Autowired
    private RestTemplate restTemplate;


/*
 @HystrixCommand
    1设置fallbackMethod的方法 入参和返回值要求和 目录方法必须是一致，否则会报错
    2如果目标方法内部出现异常，将不走目标方法，直接返回 fallbackMethod指定的方法返回值
 */

    @ResponseBody
    @GetMapping("info")
    @HystrixCommand(fallbackMethod = "infoHystrix",
            commandProperties = {
                    @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "6"), //请求的次数 6次。
                    @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "5000"), //熔断器开启判断5s
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50") //错误率50%
            }
    )
    public String info(@RequestParam("id") String id){
        /**
         * id值判断是否等于123，如果ID值不等123， 让其发生异常
         */
        if(!"123".equals(id)){

            log.info("走这个方法啦---->");
            throw  new RuntimeException("服务器发生异常错误，ID值不正确");
        }
        return "正常请求和响应得到的结果是："+id;
    }

/*服务降级：当服务内部出现异常情况，将触发降级，这个降级是每次请求都会去触发，走默认处理方法defaultFallback`
  服务熔断：在一定周期内，服务异常次数达到设定的阈值或百分比，则触发熔断，熔断后，后面的请求将都走默认处理方法`
*/
    public String infoHystrix(@RequestParam("id") String id){
         return "默认返回值是1000:"+id;
    }


    @ResponseBody
    @GetMapping("info1")
    @HystrixCommand(fallbackMethod = "infoHystrix1")
    public Object info1(@RequestParam("id") int id){
        /**
         * id值判断是否等于123，如果ID值不等123， 让其发生异常
         */
        if(!"123".equals(id)){
            throw  new RuntimeException("服务器发生异常错误，ID值不正确");
        }
        return "正常请求和响应得到的结果是："+id;
    }

    public Object infoHystrix1(@RequestParam("id") int id){
        return "info1 服务降级默认返回值是1000:"+id;
    }

    //上方的代码编写产生问题：如果每个业务都对应一个fallbackMethod方法，代码会变的非常的臃肿。

    @ResponseBody
    @GetMapping("info2")
    @HystrixCommand
    public Object info2(@RequestParam("id") int id){
        /**
         * id值判断是否等于123，如果ID值不等123， 让其发生异常
         */
        if(!"123".equals(id)){
            throw  new RuntimeException("服务器发生异常错误，ID值不正确");
        }
        return "正常请求和响应得到的结果是："+id;
    }


    public ResultJson  defaultFallback(){

        return new ResultJson("服务器开小差咯/网络繁忙，稍后再试",ResultCode.EXCEPTION);
    }
}
